﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Dolany.UtilityTool;

namespace Missbot.AIModule.Pet.PetAgainst
{
    public partial class PetAgainstEngine
    {
        private delegate string EffectDel(Dictionary<string, object> data);

        private readonly Dictionary<PetGamingEffectAttribute, EffectDel> EffectDic = new();

        public PetAgainstEngine()
        {
            var type = GetType();
            var methods = type.GetMethods().Where(m => m.CustomAttributes.Any(attr => attr.AttributeType == typeof(PetGamingEffectAttribute)));
            foreach (var method in methods)
            {
                EffectDic.AddSafe(method.GetCustomAttribute(typeof(PetGamingEffectAttribute)) as PetGamingEffectAttribute, method.CreateDelegate(typeof(EffectDel), this) as EffectDel);
            }
        }

        private string DoDemage(GamingPet source, GamingPet dest, DemageType type, int value, string title)
        {
            var realDemage = GetRealDemageValue(source, dest, type, value);
            if (realDemage <= 0)
            {
                return null;
            }

            DoRealDemage(dest, realDemage);
            var msg = $"{source.Name}对{dest.Name}造成了{realDemage}点{type.ToString()}伤害({title}),{dest.Name}剩余{dest.HP}点生命值！";
            var triggerMsg = BeAttackedTrigger(source, dest, realDemage, type);
            if (!string.IsNullOrWhiteSpace(triggerMsg))
            {
                msg += $"\n{triggerMsg}";
            }

            return msg;
        }

        private static void DoRealDemage(GamingPet dest, int realValue)
        {
            dest.HP -= realValue;
            dest.HP = Math.Max(dest.HP, 0);
        }

        private int GetRealDemageValue(GamingPet source, GamingPet dest, DemageType type, int value)
        {
            var demage = CalSourceDemage(source, type, value);
            return CalDestDemage(source, dest, type, demage);
        }

        private int CalSourceDemage(GamingPet source, DemageType type, int value)
        {
            var result = value;
            var buffs = type switch
            {
                DemageType.物理 => source.Buffs.Where(p => p.Trigger == CheckTrigger.PhyAttackFix),
                DemageType.魔法 => source.Buffs.Where(p => p.Trigger == CheckTrigger.MagicAttackFix),
                DemageType.毒系 => source.Buffs.Where(p => p.Trigger == CheckTrigger.PoisionAttackFix),
                //DemageType.真实 => 
                _ => new List<GamingBuff>()
            };
            foreach (var buff in buffs)
            {
                buff.Data.AddSafe("Source", source);
                buff.Data.AddSafe("Value", result);
                result = int.Parse(ProcessEffect(buff));
            }

            return result;
        }

        private int CalDestDemage(GamingPet source, GamingPet dest, DemageType type, int value)
        {
            var result = value;
            var buffs = type switch
            {
                DemageType.物理 => dest.Buffs.Where(p => p.Trigger == CheckTrigger.PhyDefenceFix),
                DemageType.魔法 => dest.Buffs.Where(p => p.Trigger == CheckTrigger.MagicDefenceFix),
                DemageType.毒系 => dest.Buffs.Where(p => p.Trigger == CheckTrigger.PoisionDefenceFix),
                //DemageType.真实 => 
                _ => new List<GamingBuff>()
            };
            foreach (var buff in buffs)
            {
                buff.Data.AddSafe("Source", source);
                buff.Data.AddSafe("Dest", dest);
                buff.Data.AddSafe("Value", result);
                result = int.Parse(ProcessEffect(buff));
            }

            return result;
        }
    }

    [AttributeUsage(AttributeTargets.Method)]
    public class PetGamingEffectAttribute : Attribute
    {
        public string Id { get; set; } = Guid.NewGuid().ToString();

        public string Name { get; set; }
    }

    public enum DemageType
    {
        物理,
        魔法,
        毒系,
        真实
    }
}